package com.xbongbong.saas.service.impl;


import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.instockproduct.pojo.dto.InstockProductDeleteBatchDTO;
import com.xbongbong.pro.instockproduct.pojo.dto.InstockProductListDTO;
import com.xbongbong.pro.instockproduct.pojo.vo.InstockProductDeleteBatchVO;
import com.xbongbong.pro.instockproduct.pojo.vo.InstockProductListVO;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductStockUpdateEntity;
import com.xbongbong.saas.help.workflow.InstockHelp;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.ProductStockModel;
import com.xbongbong.saas.model.ProductWarehouseModel;
import com.xbongbong.saas.model.StockFlowBillModel;
import com.xbongbong.saas.service.InstockProductService;
import com.xbongbong.saas.service.ProductSerialService;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 *
 * @author Jian.Wang
 * @version v1.0
 * @date 2019-02-21 16:01
 * @since v1.0
 **/
@Service("InstockProductService")
public class InstockProductServiceImpl implements InstockProductService{

    private static final Logger LOG = LoggerFactory.getLogger(InstockProductServiceImpl.class);

    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private ProductWarehouseModel productWarehouseModel;
    @Resource
    private ProductStockModel productStockModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private ProductSerialService productSerialService;
    @Resource
    private InstockHelp instockHelp;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private StockFlowBillModel stockFlowBillModel;

    /**
     * 入库单产品数据查询多个
     *
     * @param param 参数
     * @return List
     * @author Jian.Wang
     * @date 2019/1/23 20:27
     * @since v1.0
     */
    @Override
    public List<InstockProductEntity> findEntitys(Map<String, Object> param) {
        return instockProductModel.findEntitys(param);
    }


    @Override
    public InstockProductDeleteBatchVO deleteBatchByInstockIdIn(InstockProductDeleteBatchDTO instockProductDeleteBatchDTO) throws XbbException {
        InstockProductDeleteBatchVO instockProductDeleteBatchVO = new InstockProductDeleteBatchVO();
        try {
            // 获取入库单产品
            Map<String, Object> param = BeanUtil.convertBean2Map(instockProductDeleteBatchDTO, true);
            param.put("del", DelEnum.NORMAL.getDel());
            List<InstockProductEntity> instockProductList = instockProductModel.findEntitys(param);
            if (Objects.isNull(instockProductList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            instockProductDeleteBatchVO.setInstockProductList(instockProductList);
            String corpid = instockProductDeleteBatchDTO.getCorpid();
            List<Long> instockIdIn = instockProductDeleteBatchDTO.getInstockIdIn();
            // 删除入库单产品更新产品序列号信息 这一步必须放在删除关联产品之上
            productSerialService.deleteSerial(corpid, instockIdIn, instockProductDeleteBatchDTO.getBusinessType());
            instockProductModel.deleteByInstockIdIn(corpid, instockIdIn);
        } catch (Exception e) {
            LOG.error("instockProductServiceImpl.deleteBatch 批量删除出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return instockProductDeleteBatchVO;
    }

    @Override
    public InstockProductListVO findInstockProductList(InstockProductListDTO instockProductListDTO) throws XbbException {
        InstockProductListVO instockProductListVO = new InstockProductListVO();
        try {
            // 获取入库单产品
            Map<String, Object> param = BeanUtil.convertBean2Map(instockProductListDTO, true);
            List<InstockProductEntity> instockProductList = instockProductModel.findEntitys(param);
            if (Objects.isNull(instockProductList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            instockProductListVO.setInstockProductList(instockProductList);
        } catch (Exception e) {
            LOG.error("instockProductServiceImpl.deleteBatch 批量删除出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return instockProductListVO;
    }

    @Override
    public Map<Long, ProductStockUpdateEntity> delUpdateStock(List<InstockProductEntity> instockProductList, String corpid, boolean isFormOri, Set<Long> disableBatchProducts) throws XbbException {
        Map<Long,ProductStockUpdateEntity> productUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductStockUpdateEntity> warehouseProductUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, ProductStockUpdateEntity> batchProductUpdateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Boolean batchShelf = companyConfigModel.getBatchShelf(corpid);
        for (InstockProductEntity entity : instockProductList){
            if (Objects.equals(entity.getProductDel(),1) || Objects.equals(entity.getWarehouseDel(),1)) {
                //产品删除或者仓库删除不需要更新库存
                continue;
            }
            double amendNum = entity.getProductNum() == null ? 0D : entity.getProductNum();
            //库存减少业务
            amendNum = -amendNum;
            double amendCost = entity.getCost() == null ? 0D : entity.getCost();
            Long productId = entity.getProductId();
            String warehouseKey = productId + "_" + entity.getWarehouseId();
            // 全仓库存数据
            String allWarehouseKey = productId + "_" + 0;
            if (productUpdateMap.containsKey(entity.getProductId())){
                ProductStockUpdateEntity productStockUpdateEntity = productUpdateMap.get(entity.getProductId());
                productStockUpdateEntity.updateStock(amendNum,amendCost);
                productUpdateMap.put(entity.getProductId(),productStockUpdateEntity);
            }else {
                ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(productId,amendNum,amendCost);
                productUpdateMap.put(entity.getProductId(),productStockUpdateEntity);
            }
            //分仓数量
            if (warehouseProductUpdateMap.containsKey(warehouseKey)){
                ProductStockUpdateEntity productStockUpdateEntity = warehouseProductUpdateMap.get(warehouseKey);
                productStockUpdateEntity.updateStock(amendNum,amendCost);
                warehouseProductUpdateMap.put(warehouseKey,productStockUpdateEntity);
            }else {
                ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(warehouseKey,amendNum,amendCost);
                warehouseProductUpdateMap.put(warehouseKey,productStockUpdateEntity);
            }
            //总仓数量
            if (warehouseProductUpdateMap.containsKey(allWarehouseKey)){
                ProductStockUpdateEntity productStockUpdateEntity = warehouseProductUpdateMap.get(allWarehouseKey);
                productStockUpdateEntity.updateStock(amendNum,amendCost);
                warehouseProductUpdateMap.put(allWarehouseKey,productStockUpdateEntity);
            }else {
                ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(allWarehouseKey,amendNum,amendCost);
                warehouseProductUpdateMap.put(allWarehouseKey,productStockUpdateEntity);
            }
            //公司级配置没有开启批次或者单个产品没有开启批次的话不需要跟新批次库存
            if (Objects.nonNull(entity.getBatch()) && batchShelf && !disableBatchProducts.contains(entity.getParentId())) {
                //批次数量
                String batchKey = productId + "_" + entity.getWarehouseId() + "_" + entity.getBatch() + "_" + entity.getProduceDate() + "_" + entity.getGuaranteePeriod();
                if (batchProductUpdateMap.containsKey(batchKey)){
                    ProductStockUpdateEntity productStockUpdateEntity = batchProductUpdateMap.get(batchKey);
                    productStockUpdateEntity.updateStock(amendNum,amendCost);
                    batchProductUpdateMap.put(batchKey,productStockUpdateEntity);
                }else {
                    ProductStockUpdateEntity productStockUpdateEntity = new ProductStockUpdateEntity(batchKey,amendNum,amendCost);
                    batchProductUpdateMap.put(batchKey,productStockUpdateEntity);
                }
            }
        }
        productStockModel.updateStockDB(batchProductUpdateMap.keySet(), batchProductUpdateMap.values(),corpid);
        productWarehouseModel.updateStockDB(warehouseProductUpdateMap.keySet(), warehouseProductUpdateMap.values(),corpid, isFormOri);
        return productUpdateMap;
    }

    @Override
    public Map<Long, ProductStockUpdateEntity> addUpdateStock(List<InstockProductEntity> instockProductList, String corpid, Boolean isFromOri) throws XbbException {
        return instockHelp.addUpdateStock(instockProductList, corpid, isFromOri);
    }

}
